package utsc.apps.utschedule.widget;

import utsc.apps.utschedule.R;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.Paint.FontMetricsInt;
import android.graphics.Paint.Style;
import android.preference.PreferenceManager;
import android.text.format.Time;
import android.util.AttributeSet;
import android.view.View;

/*
 * Copyright 2011 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * This class is a modified version of the TimRulerView from Google.
 * <br/>The modified version simply added a customizable column feature.
 * @author Wenbin
 *
 */
public class TimeRulerGridView extends View {

	private int _HeaderWidth = 40;
    private int _HourHeight = 120;
    private boolean _HorizontalDivider = true;
    private int _column=5;
    private int _columnWidth=-1;
    private int _LabelTextSize = 20;
    private int _LabelPaddingLeft = 8;
    private int _LabelColor = Color.BLACK;
    private int _ColumnHeaderColor = Color.LTGRAY;
    private int _DividerColor = Color.LTGRAY;
    private int _GridColor = Color.WHITE;
    private static int _StartHour = 8;
    private static int _EndHour = 23;
	
    private int[][] _xAxisRanges,_yAxisRanges;
    private static String[][] _hoursString; 
    
    public TimeRulerGridView(Context context) {
        this(context, null);
    }

    public TimeRulerGridView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
    
	public TimeRulerGridView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		SharedPreferences settings=PreferenceManager.getDefaultSharedPreferences(context);
		int startHourSetting=Integer.parseInt(settings.getString("start_hour", "8"));
		int endHourSetting=Integer.parseInt(settings.getString("end_hour", "22"))+1;
		 final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TimeRulerGridView,
	                defStyle, 0);
		 
		 _HeaderWidth = a.getDimensionPixelSize(R.styleable.TimeRulerGridView_headerWidth,  _HeaderWidth);
	        _HourHeight = a
	                .getDimensionPixelSize(R.styleable.TimeRulerGridView_hourHeight, _HourHeight);
	       /* _LabelTextSize = a.getDimensionPixelSize(R.styleable.TimeRulerGridView_labelTextSize,
	                _LabelTextSize);
	        _LabelPaddingLeft = a.getDimensionPixelSize(R.styleable.TimeRulerGridView_labelPaddingLeft,
	                _LabelPaddingLeft);
	        */
	        _LabelColor = a.getColor(R.styleable.TimeRulerGridView_labelColor, _LabelColor);
	        _ColumnHeaderColor = a.getColor(R.styleable.TimeRulerGridView_columnHeaderColor, _ColumnHeaderColor);
	        /*_DividerColor = a.getColor(R.styleable.TimeRulerGridView_dividerColor, _DividerColor);*/
	        _GridColor = a.getColor(R.styleable.TimeRulerGridView_gridColor, _GridColor);
	       /* _StartHour = a.getInt(R.styleable.TimeRulerGridView_startHour, _StartHour);
	        _EndHour = a.getInt(R.styleable.TimeRulerGridView_endHour, _EndHour);*/
		 _column=a.getInt(R.styleable.TimeRulerGridView_column, _column);
		 setBackgroundColor(_GridColor);
	        a.recycle();
		//_HeaderWidth=getResources().getDimensionPixelSize(R.dimen.timeruler_header_width);
		//_HourHeight=getResources().getDimensionPixelSize(R.dimen.timeruler_header_height);
		setClickable(false);
		setupHourString(startHourSetting,endHourSetting);
	}
	
	/**
     * Return the vertical offset (in pixels) for a requested time (in
     * milliseconds since epoch).
     */
    public int getTimeVerticalOffset(long timeMillis) {
        Time time = new Time();
        time.set(timeMillis);
 
        final int minutes = ((time.hour - _StartHour) * 60) + time.minute;
        return (minutes * _HourHeight) / 60;
    }

    public int getTimeHourBlockPosition(float y){
    	int length=_yAxisRanges.length;
    	int startRange;
    	int endRange;
    	for (int i = 0; i < length; i++) {
    		startRange=_yAxisRanges[i][0];
    		endRange=_yAxisRanges[i][1];
			if (y>=startRange && y<=endRange) {
				return i+_StartHour;
			}
		}
    	return (int)(y/_HourHeight)+_StartHour;
    }
    
    /**
     * This is a helper method to convert the screen x position to the corresponding column position.
     * 
     * @param x
     * @return - the corresponding column position on the grid
     */
    public int getTimeColumnBlockPosition(float x){
    	int length=_xAxisRanges.length;
    	int startRange;
    	int endRange;
    	for (int i = 0; i < length; i++) {
    		startRange=_xAxisRanges[i][0];
    		endRange=_xAxisRanges[i][1];
			if (x>=startRange && x<=endRange) {
				return i+1;
			}
		}
    	return (int)(x/_columnWidth)+1;
    }
    
    @Override
    protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        final int hours = _EndHour - _StartHour;

        int width = _HeaderWidth;
        int height = _HourHeight * hours;

        setMeasuredDimension(resolveSize(width, widthMeasureSpec),
                resolveSize(height, heightMeasureSpec));
    }

    private Paint mDividerPaint = new Paint();
    private Paint mLabelPaint = new Paint();
    private Paint mHeaderPaint=new Paint();

    @Override
    protected synchronized void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        
        final int hourHeight = _HourHeight;

        final Paint dividerPaint = mDividerPaint;
        dividerPaint.setColor(_DividerColor);
        dividerPaint.setStyle(Style.FILL);
        
        final Paint headerPaint = mHeaderPaint;
        headerPaint.setColor(_ColumnHeaderColor);
        headerPaint.setStyle(Style.FILL);

        final Paint labelPaint = mLabelPaint;
        labelPaint.setColor(_LabelColor);
        labelPaint.setTextSize(_LabelTextSize);
        labelPaint.setTypeface(Typeface.DEFAULT_BOLD);
        labelPaint.setAntiAlias(true);

        final FontMetricsInt metrics = labelPaint.getFontMetricsInt();
        final int labelHeight = Math.abs(metrics.ascent);
        final int labelOffset = labelHeight + _LabelPaddingLeft;

        final int right = getRight();
        final Rect hourPostfixBounds=new Rect();
        labelPaint.getTextBounds(_hoursString[0][0], 0,1,hourPostfixBounds);

        //draw the column lines first
        for (int i = 0; i < _column; i++) {
        	canvas.drawLine(i*_columnWidth+_HeaderWidth, 0, i*_columnWidth+_HeaderWidth, getHeight(), dividerPaint);
		}
        // Walk left side of canvas drawing timestamps
        final int hours = _EndHour - _StartHour;
        for (int i = 0; i < hours; i++) {
            final int dividerY = hourHeight * i;
            final int nextDividerY = hourHeight * (i + 1);
            
            
            // draw text title for timestamp
            canvas.drawRect(0, dividerY, _HeaderWidth, nextDividerY, headerPaint);
            
            canvas.drawLine(0, dividerY, right, dividerY, dividerPaint);

            // TODO: localize these labels better, including handling
            // 24-hour mode when set in framework.
            /*final int hour = _StartHour + i;
            String label, hourPostfix="am";
            if (hour == 0) {
                label = "12";//am
                hourPostfix="am";
            } else if (hour <= 11) {
                label = hour + "";//am
                hourPostfix="am";
            } else if (hour == 12) {
                label = "12";//pm
                hourPostfix="pm";
            } else {
                label = (hour - 12) + "";//pm
                hourPostfix="pm";
            }*/
            final String label=_hoursString[i][0];
            final String hourPostfix=_hoursString[i][1];
            final float labelWidth = labelPaint.measureText(label);

            canvas.drawText(label, 0, label.length(), _HeaderWidth - labelWidth
                    - _LabelPaddingLeft, dividerY + labelOffset, labelPaint);
            final float hourLabelWidth = labelPaint.measureText(hourPostfix);
            canvas.drawText(hourPostfix, 0, hourPostfix.length(), _HeaderWidth - hourLabelWidth-_LabelPaddingLeft, dividerY + labelOffset+hourPostfixBounds.height(), labelPaint);
        }
    }

    private void setupHourString(int newStartHour, int newEndHour){
    	if (_hoursString==null || (newStartHour!=_StartHour || newEndHour !=_EndHour)) {
    		_StartHour=newStartHour;
    		_EndHour=newEndHour;
    		final int hours = _EndHour - _StartHour;
        	_hoursString=new String[hours][2];
        	//StringBuilder stringBuilder=new StringBuilder();
        	
            for (int i = 0; i < hours; i++) {
                // TODO: localize these labels better, including handling
                // 24-hour mode when set in framework.
                final int hour = _StartHour + i;
                String label, hourPostfix="am";
                if (hour == 0) {
                    label = "12";//am
                    hourPostfix="am";
                } else if (hour <= 11) {
                    label = Integer.toString(hour);//am
                    hourPostfix="am";
                } else if (hour == 12) {
                    label = "12";//pm
                    hourPostfix="pm";
                } else {
                    label = Integer.toString(hour - 12) ;//pm
                    hourPostfix="pm";
                }
                _hoursString[i][0]=label;
                _hoursString[i][1]=hourPostfix;
            }
		}
    	
    }
    
    @Override
    protected void onLayout(boolean changed, int left, int top, int right,
    		int bottom) {
    	super.onLayout(changed, left, top, right, bottom);
    	//setup the x and y axis ranges when first drawing the layout
        if (_columnWidth==-1) {
			_columnWidth=(getWidth()-_HeaderWidth)/_column;
			
			int totalHours=_EndHour-_StartHour;
			_xAxisRanges=new int[_column][2];
			_yAxisRanges=new int[totalHours][2];
			for (int i = 0; i < totalHours; i++) {
				_yAxisRanges[i][0]=i*_HourHeight;
				_yAxisRanges[i][1]=_yAxisRanges[i][0]+_HourHeight;
			}
			for (int i = 0; i < _column; i++) {
				_xAxisRanges[i][0]=i*_columnWidth+_HeaderWidth;
				_xAxisRanges[i][1]=_xAxisRanges[i][0]+_columnWidth;
			}
			
		}
    }
    public int get_StartHour() {
		return _StartHour;
	}
    public int getHeaderWidth() {
        return _HeaderWidth;
    }
    
    public int get_HourHeight() {
		return _HourHeight;
	}
    
    public int get_columnWidth() {
		return _columnWidth;
	}
    
    public int get_column() {
		return _column;
	}

}
